package com.syh.jn.scm.domain.supplier.entity.base.goods;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.jn.scm.domain.supplier.repository.base.ProjectItemReadRepository;
import com.syh.jn.scm.domain.supplier.repository.base.downstream.DownstreamPriceTemplateRepository;
import com.syh.jn.scm.domain.supplier.repository.base.goods.GoodsCategoryRepository;
import com.syh.jn.scm.domain.supplier.repository.base.upstream.UpstreamNewGoodsRequestReadRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurReturnOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleReturnOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.stock.StockLossReadRepository;
import com.syh.jn.scm.domain.supplier.repository.stock.StockRecordReadRepository;
import com.syh.jn.scm.domain.supplier.repository.stock.StockSpillReadRepository;
import com.syh.jn.scm.dto.supplier.base.goods.GoodsMto;
import com.syh.jn.scm.dto.supplier.base.goods.GoodsSto;
import com.syh.jn.scm.exception.BusinessException;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.util.UUID;

/**
 * 商品
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class Goods extends AbstractSimpleAggregate<Long> {

    /**
     * 商品名称
     */
    private String name;
    /**
     * 编码
     */
    private String code;
    /**
     * 供应商扩展编码
     */
    private String extCode;
    /**
     * 分类id
     */
    private Long categoryId;
    /**
     * 归属id
     */
    private Long businessEntityId;
    /**
     * 所属种类,应用分类编码
     */
    private String categoryCatalogCode;
    /**
     * 所属种类,应用分类名称
     */
    private String categoryName;
    /**
     * 品牌id
     */
    private Long goodsBrandId;
    /**
     * 产地id
     */
    private Long originId;
    /**
     * 生产商id
     */
    private Long manufacturerId;
    /**
     * 规格名称
     */
    private String specName;
    /**
     * 计量单位
     */
    private String units;
    /**
     * 条码
     */
    private String codeBar;
    /**
     * 是否可用: -1停用,1可用
     */
    private Short status;
    /**
     * 默认销售税率
     */
    private BigDecimal salesTaxRate;
    /**
     * 默认采购税率
     */
    private BigDecimal purchaseTaxRate;
    /**
     * -1 辅助商品  1  基础商品
     */
    private Short isDefaultGoods;
    /**
     * 基础商品id （如果是基础商品 则指向他自己）
     */
    private Long defaultGoodsId;
    /**
     * 与基础商品转换率（如果是基础商品 则等于1）
     */
    private BigDecimal conversionRate;
    /**
     * 图片url,保存格式json字符串{"img":"www.test.com","img":"www.demo.com"}
     */
    private String imgUrl;
    /**
     * 商品描述
     */
    private String goodsDescribe;

    /**
     * 新建商品
     *
     * @param sto
     * @return
     */
    public static Goods createGoods(GoodsSto sto) {
        ExtAssert.notNull(sto, "对象为空");
        ValidationUtils.validate(sto);
        Goods goods = Goods.systemCreate(sto);
        goods.setUuid(UUID.randomUUID().toString());
        return goods;
    }

    /**
     * 启用
     */
    public void enabled() {
        GoodsCategoryRepository goodsCateQuery = (GoodsCategoryRepository) SpringContextUtils.getBean(GoodsCategoryRepository.class);
        GoodsCategory goodsCate = goodsCateQuery.getById(this.categoryId);
        if (!goodsCate.getStatus().equals(Short.valueOf("1")))
            throw new BusinessException("该商品所属分类未启用！请先启用分类");
        this.status = Short.valueOf("1");
    }

    /**
     * 停用
     */
    public void disabled() {
        this.status = Short.valueOf("-1");
    }

    /**
     * 修改商品
     *
     * @param mto
     */
    public void modify(GoodsMto mto) {
        ExtAssert.notNull(mto, "对象为空");
        ValidationUtils.validate(mto);
        ExtBeanUtils.copyProperties(mto, this);
        this.lastUpdateTimeStamp = System.currentTimeMillis();
    }

    /**
     * 数据销毁
     */
    public void destroy() {
        Wrapper wp = Wrapper.build().append(Restrictions.eq("goodsId", id));

        //删除前查看是否已经被引用，被引用则不允许删除
        DownstreamPriceTemplateRepository cqRepository = (DownstreamPriceTemplateRepository) SpringContextUtils.getBean(DownstreamPriceTemplateRepository.class);
        if (cqRepository.downstreamPriceTmplDetailExistsByColumn("goodsId", id)) {
            throw new BusinessException("该商品已被商品模板关联,删除失败!");
        }
        //删除前查看是否已经存在订单，存在则不允许删除
        PurchaseOrderReadRepository poRepository = (PurchaseOrderReadRepository) SpringContextUtils.getBean("purchaseOrderRepositoryImpl");
        if (poRepository.purItemExistsById("goodsId", id)) {
            throw new BusinessException("该商品已存在采购订单,删除失败!");
        }
        PurReturnOrderReadRepository proRepository = (PurReturnOrderReadRepository) SpringContextUtils.getBean(PurReturnOrderReadRepository.class);
        if (proRepository.purReturnItemExistsById("goodsId", id)) {
            throw new BusinessException("该商品已存在采购退货订单,删除失败!");
        }
        SaleOrderReadRepository soRepository = (SaleOrderReadRepository) SpringContextUtils.getBean("saleOrderRepositoryImpl");
        if (soRepository.saleItemExistsById("goodsId", id)) {
            throw new BusinessException("该商品已存在销售订单,删除失败!");
        }
        SaleReturnOrderReadRepository sroRepository = (SaleReturnOrderReadRepository) SpringContextUtils.getBean(SaleReturnOrderReadRepository.class);
        if (sroRepository.saleReturnItemExistsById("goodsId", id)) {
            throw new BusinessException("该商品已存在销售退货订单,删除失败!");
        }
        StockLossReadRepository slRepository = (StockLossReadRepository) SpringContextUtils.getBean(StockLossReadRepository.class);
        if (slRepository.stockLossItemExistsById("goodsId", id)) {
            throw new BusinessException("该商品已存在报损订单,删除失败!");
        }
        StockSpillReadRepository sofRepository = (StockSpillReadRepository) SpringContextUtils.getBean(StockSpillReadRepository.class);
        if (sofRepository.stockSpillItemExistsById("goodsId", id)) {
            throw new BusinessException("该商品已存在报溢订单,删除失败!");
        }
        StockRecordReadRepository srRepository = (StockRecordReadRepository) SpringContextUtils.getBean("stockRecordRepositoryImpl");
        if (srRepository.stockRecordItemExistsById("goodsId", id)) {
            throw new BusinessException("该商品已存在库存记录,删除失败!");
        }
        ProjectItemReadRepository piReadRepository = (ProjectItemReadRepository) SpringContextUtils.getBean(ProjectItemReadRepository.class);
        if (piReadRepository.getCount(wp) > 0) {
            throw new BusinessException("该商品已被运营项目关联,删除失败!");
        }
        UpstreamNewGoodsRequestReadRepository usGoodsAppReadRepository = (UpstreamNewGoodsRequestReadRepository) SpringContextUtils.getBean(UpstreamNewGoodsRequestReadRepository.class);
        if (usGoodsAppReadRepository.getCount(Wrapper.build().append(Restrictions.eq("associatedGoodsId", id))) > 0) {
            throw new BusinessException("该商品已存在上游商品中,删除失败!");
        }

    }

    /**
     * 系统默认生成的字段
     *
     * @param sto
     * @return
     */
    private static Goods systemCreate(GoodsSto sto) {
        Goods goods = new Goods();
        ExtBeanUtils.copyProperties(sto, goods);
        goods.createTimeStamp = System.currentTimeMillis();
        goods.status = Short.valueOf("1");
        return goods;
    }


}
